#!/usr/bin/perl -w
#
# Copyright(c) Plink Limited 2010. All rights reserved.
#
# $Header:$
#
# $Log:$
# 
# Author:      Jeremy Banks
#
# Description: Hold the parsed configuration information
#

#----------------------------------------------------------------------
# External Modules
#----------------------------------------------------------------------

package XMLTV::Configuration;

use strict;

use CGI::Cookie;
use Data::Dumper;
use XML::Simple;

use XMLTV::Channel;
use XMLTV::Logger;
use XMLTV::Settings;
use XMLTV::Source;

#---------------------------------------------------------------------------
# Constructor
#---------------------------------------------------------------------------

sub new
{
   my $class = shift;
   
   my $self = bless {}, $class;
   $self->{_channels} = [];
   $self->{_sources} = [];
   $self->{_defaults} = {};
   $self->{_channel_names} = {};
   $self->{_logger} = XMLTV::Logger->instance();

   _load_config($self);
   return $self;
}

#----------------------------------------------------------------------
# Load the configuration file
#----------------------------------------------------------------------

sub _load_config
{
   my $self = shift;
   my $file = XMLTV::Settings::marker_file();
   my $doc = XMLin($file);
   $self->{_logger}->die("Couldn't load config file $file") unless $doc;

   _load_channels($self, $doc);
   _load_sources($self, $doc);
}

#----------------------------------------------------------------------
# Load channels
#----------------------------------------------------------------------

sub _load_channels
{
   my ($self, $doc) = @_;

   my %channels = %{$$doc{Channels}{Channel}};
   for (keys %channels)
   {
      my $xml = $channels{$_};
      my $channel = XMLTV::Channel->new();

      $channel->id($$xml{cid});
      $channel->name($_);
      $channel->virtual_channel($$xml{virtual_channel} || 0);
      $channel->icon($$xml{icon}) if $$xml{icon};
      $channel->longest_show_period($$xml{longestshowperiod} || 0);
      $self->{_defaults}{$channel->id()} = $$xml{default};
      $self->{_channels_by_id}{$channel->id()} = $channel;

      push @{$self->{_channels}}, $channel;
   }
}

#----------------------------------------------------------------------
# Load sources
#----------------------------------------------------------------------

sub _load_sources
{
   my ($self, $doc) = @_;

   my %sources = %{$$doc{Source}};
   for (keys %sources)
   {
      my $xml = $sources{$_};
      my $source = XMLTV::Source->new();

      $source->name($_);
      $source->prefix($$xml{prefix});
      $source->enabled(!$$xml{Enabled} or "false" ne lc $$xml{Enabled});
      $source->adjust_start_time(!$$xml{AdjustStartTime} or "false" ne lc $$xml{AdjustStartTime});
      $source->timezone_minute_adjust($$xml{TimeZoneMinuteAdjust} || 0);

#      next unless $$doc{Channels} and $$source{Channels}{Channel};
      my %channels = %{$$doc{Channels}{Channel}};
      if (0 < scalar keys %channels)
      {
         $source->type(XMLTV::Source::MULTIPLE_TYPE);
         for (values %channels)
         {
            my $this_channel = $self->{_channels_by_id}{$$_{cid}};
            unless ($this_channel)
            {
               $self->{_logger}->log("Couldn't locate matching channel for channel id: " .
                                     $$_{cid});
               next;
            }
            my $channel = XMLTV::Channel->new();
            $channel->id($$_{cid});
            $channel->name($this_channel->name());
            $channel->code($$_{code});
            $channel->adjust($$_{adjust}) if $$_{adjust};
            if ($$_{cookies})
            {
               my %cookies = %{$$source{TVShowList}{ListPage}{Cookies}{Cookie}};
               for my $cookie_name (split /[\,\;\|]/, $$_{cookies})
               {
                  for (keys %cookies)
                  {
                     my $xml_cookie = $cookies{$_};
                     push @{$channel->cookies()},
                        new CGI::Cookie(-name   => $$xml_cookie{name},
                                        -value  => $$xml_cookie{value},
                                        -domain => $$xml_cookie{domain})
                           if $cookie_name eq $$xml_cookie{id};
                  }
               }
            }

            $channel->virtual_channel($this_channel->virtual_channel());
            $channel->icon($this_channel->icon());
            $channel->longest_show_period($this_channel->longest_show_period());
            push @{$source->support_channels}, $channel;
         }
      }
      else
      {
         $source->type(XMLTV::Source::SINGLE_TYPE);
         for (@{$self->{_channels}})
         {
            if ($$_->name() eq $source->name())
            {
               push @{$source->support_channels}, $_;
               last;
            }
         }
      }

      push @{$self->{_sources}}, $source;
   }
}

#----------------------------------------------------------------------
# String representation of this object
#----------------------------------------------------------------------

sub to_string
{
   my $self = shift;
   my $str = "XMLTV::Configuration\nChannels:\n";
   $str .= $_->to_string() . "\n" for @{$self->{_channels}};
   $str .= "Sources:\n";
   $str .= $_->to_string() . "\n" for @{$self->{_sources}};
   return $str;
}


1;
